﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace HowItWentDown
{
    public class Companion : Obj
    {
        private enum Mood { Neutral, Happy, Sad, Angry, Retreating };
        private Dictionary<string, Texture2D> moodTextures;
        private Mood mood = Mood.Neutral;
        private int[] moodCounter;
        private const int COUNTER_MAX = 5;

        public int health = 100;

        private int proxyCooldown = 0;
        private int retreatCooldown = 0;
        public int hugCooldown = 0;
        public int insultCooldown = 0;
        private int moodCooldown = 0;
        private int damageCooldown = 0;
        //Vector3 acc = Vector3.Zero;
        Vector3 velocity2 = Vector3.Zero;
        float speed = 0;
        float acc = 0;

        Obj target;

        public Companion(Game1 game, float X, float Y, float Z)
            : base(game, X, Y, Z, Global.LoadTexture("Companion/indifferent-2"))
        {
            stationary = false;
            floating = false;
            collision = true;
            pickable = false;
            climbable = false;
            lookAtCamera = true;

            mood = Mood.Neutral;

            moodTextures = new Dictionary<string, Texture2D>();
            moodTextures.Add("neutral", Global.LoadTexture("Companion/indifferent-2"));
            moodTextures.Add("happy", Global.LoadTexture("Companion/love-2"));
            moodTextures.Add("sad", Global.LoadTexture("Companion/sad"));
            moodTextures.Add("angry", Global.LoadTexture("Companion/anger-2"));
            scale = 0.32f;

            moodCounter = new int[4];

            Global.Companion = this;

            target = Global.Player;
        }

        public override void Update()
        {
            proxyCooldown++;

            //check collision with shadow enemy projectiles
            foreach (Obj collisionObject in doc.objList)
            {
                if (collisionObject.GetType() == typeof(Enemies.ShadowBall))
                {
                    collisionObject.collisionBox = new BoundingBox(new Vector3(collisionObject.pos.X, collisionObject.pos.Y, collisionObject.pos.Z - 10), new Vector3(collisionObject.pos.X + (collisionObject.rect.Width * collisionObject.scale), collisionObject.pos.Y + (collisionObject.rect.Height * collisionObject.scale), collisionObject.pos.Z + 10));

                    if (this.collisionBox.Intersects(collisionObject.collisionBox))
                    {
                        health -= 10;
                        if (health <= 0)
                        {
                            health = 0;
                            mood = Mood.Retreating;
                        }
                        collisionObject.remove();
                        increaseSad(1);
                        break;
                    }
                }

            }
            // In the time it takes to take your finger off of the C key, the mood change iterates multiple times, this is a cooldown
            moodCooldown++;
            if (moodCooldown > 180)
                moodCooldown = 60;
            // Cycle the companions mood to test functionality
            if (Controls.GetKey(Keys.C) == ControlState.Held && moodCooldown >= 60)
            {
                moodCooldown = 0;
                if (mood == Mood.Angry)
                    mood = Mood.Neutral;
                else
                    mood++;
            }

            //hugging 
            if (hugCooldown < 600)
                hugCooldown++;
            if (Controls.GetKey(Keys.Z) == ControlState.Held && hugCooldown == 600 && mood != Mood.Happy && Vector3.Distance(pos, Global.Player.pos) < 50)
            {
                hugCooldown = 0;
                increaseHappy(3);
            }

            //insulting
            if (insultCooldown < 300)
                insultCooldown++;
            if (Controls.GetKey(Keys.X) == ControlState.Held && insultCooldown == 300 && mood != Mood.Angry && Vector3.Distance(pos, Global.Player.pos) < 50)
            {
                insultCooldown = 0;
                increaseAngry(3);
            }

            //change target
            if (Controls.GetKey(Keys.V) == ControlState.Pressed && doc.target != null)
                target = doc.target;

            //reset target to player
            if (Controls.GetKey(Keys.Q) == ControlState.Pressed)
                target = Global.Player;

            //deal damage to enemies
            if (damageCooldown < 180)
                damageCooldown++;
            if (target is Enemy && damageCooldown == 180 && Vector3.Distance(pos, target.pos) < 50) 
            {
                damageCooldown = 0;
                (target as Enemy).takeDamage(5);
                if ((target as Enemy).health == 0)
                    target = Global.Player;
            }


            #region moods
            //load textures
            switch (mood)
            {
                #region neutral
                case Mood.Neutral:
                    {
                        if (this.tex != moodTextures["neutral"])
                        {
                            this.tex = moodTextures["neutral"];
                            scale = 0.32f;
                        }

                        float dist = Vector3.Distance(pos, target.pos);
                        if (dist > 65)
                        {
                            acc = 0.02f;
                        }

                        else if (dist < 45)
                        {
                            acc = -0.03f;
                        }
                        speed += acc;
                        if (speed < 0)
                            speed = 0;
                        else if (speed > 1)
                            speed = 1;
                        velocity = Extensions.Normalize(target.pos - pos, speed);
                        y = 0;

                        break;
                    }
                #endregion
                #region happy
                case Mood.Happy:
                    {
                        if (this.tex != moodTextures["happy"])
                        {
                            this.tex = moodTextures["happy"];
                            scale = 0.32f;
                        }

                        float dist = Vector3.Distance(pos, target.pos);
                        if (dist > 40)
                        {
                            acc = 0.03f;
                        }

                        else if (dist < 30)
                        {
                            acc = -0.03f;
                        }
                        speed += acc;
                        if (speed < 0)
                            speed = 0;
                        else if (speed > 1)
                            speed = 1f;
                        if (proxyCooldown >= 300 && Vector3.Distance(pos, Global.Player.pos) <= 25)
                        {
                            heal();
                            proxyCooldown = 0;
                        }
                        velocity = Extensions.Normalize(target.pos - pos, speed);
                        y = 0;

                        break;
                    }
                #endregion
                #region sad
                case Mood.Sad:
                    {
                        if (this.tex != moodTextures["sad"])
                        {
                            this.tex = moodTextures["sad"];
                            scale = 0.32f;
                        }

                        float dist = Vector3.Distance(pos, target.pos);
                        if (dist > 75)
                        {
                            acc = 0.01f;
                        }

                        else if (dist < 45)
                        {
                            acc = -0.03f;
                        }
                        speed += acc;
                        if (speed < 0)
                            speed = 0;
                        else if (speed > .75)
                            speed = .65f;
                        velocity = Extensions.Normalize(target.pos - pos, speed);
                        y = 0;

                        break;
                    }
                #endregion
                #region angry
                case Mood.Angry:
                    {
                        if (this.tex != moodTextures["angry"])
                        {
                            this.tex = moodTextures["angry"];
                            scale = 0.32f;
                        }

                        float dist = Vector3.Distance(pos, target.pos);
                        if (dist > 40)
                        {
                            acc = 0.03f;
                        }

                        else if (dist < 30)
                        {
                            acc = -0.03f;
                        }
                        speed += acc;
                        if (speed < 0)
                            speed = 0;
                        else if (speed > 1)
                            speed = 1f;

                        if (proxyCooldown >= 300 && Vector3.Distance(pos, Global.Player.pos) <= 25)
                        {
                            hit();
                            proxyCooldown = 0;
                        }
                        velocity = Extensions.Normalize(target.pos - pos, speed);
                        y = 0;

                        break;
                    }
                #endregion
                #region retreating
                case Mood.Retreating:
                    {
                        retreatCooldown++;
                        if (this.tex != moodTextures["sad"])
                        {
                            this.tex = moodTextures["sad"];
                            scale = 0.32f;
                        }
                        pos += new Vector3(1.5f, 0, 0);
                        if (retreatCooldown >= 720)
                        {
                            resetMood();
                            health = 100;
                        }

                        break;
                    }
                #endregion
            #endregion
            }
            if (proxyCooldown < 300)
                proxyCooldown++;
            base.Update();
        }

        public void increaseNeutral(int inc)
        {
            moodCounter[0] += inc;
            if (moodCounter[0] >= COUNTER_MAX)
            {
                mood = Mood.Neutral;
                moodCounter[0] = 0;
                for (int i = 1; i < moodCounter.Length; i++)
                {
                    moodCounter[i] -= 3;
                    if (moodCounter[i] < 0)
                        moodCounter[i] = 0;
                }
            }
        }

        public void increaseHappy(int inc)
        {
            moodCounter[1] += inc;
            if (moodCounter[1] >= COUNTER_MAX)
            {
                mood = Mood.Happy;
                moodCounter[1] = 0;
                for (int i = 0; (i < moodCounter.Length) && (i != 1); i++)
                {
                    moodCounter[i] -= 3;
                    if (moodCounter[i] < 0)
                        moodCounter[i] = 0;
                }
            }
        }

        public void increaseAngry(int inc)
        {
            moodCounter[2] += inc;
            if (moodCounter[2] >= COUNTER_MAX)
            {
                mood = Mood.Angry;
                moodCounter[2] = 0;
                for (int i = 0; (i < moodCounter.Length) && (i != 2); i++)
                {
                    moodCounter[i] -= 3;
                    if (moodCounter[i] < 0)
                        moodCounter[i] = 0;
                }
            }
        }

        public void increaseSad(int inc)
        {
            moodCounter[3] += inc;
            if (moodCounter[3] >= COUNTER_MAX)
            {
                mood = Mood.Sad;
                moodCounter[3] = 0;
                for (int i = 0; i < moodCounter.Length - 1; i++)
                {
                    moodCounter[i] -= 3;
                    if (moodCounter[i] < 0)
                        moodCounter[i] = 0;
                }
            }
        }

        public void resetMood()
        {
            mood = Mood.Neutral;
            for (int i = 0; i < moodCounter.Length; i++)
            {
                moodCounter[i] = 0;
            }
        }

        public void setTarget(Obj target)
        {
            this.target = target;
        }

        public void heal()
        {
            Global.Player.health += 5;
        }

        public void hit()
        {
            Global.Player.health -= 5;
        }


    }
}
